package model.generator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;

import util.TimeBlock;
import util.enums.CourseDay;

import model.Course;
import model.OfferedCourse;
import model.container.CourseContainer;
import model.container.RegistrationContainer;
import model.container.TeacherContainer;
import model.enums.Classroom;
import model.enums.CourseMinutes;
import model.generator.enums.CourseName;

public class CourseGenerator {
	
	private static Random random = new Random();

	/** Generates a predefined number of courses */
	public static ArrayList<Course> generateCourses() {

		// Initialize list
		ArrayList<Course> courses = new ArrayList<Course>();
		CourseName[] courseNames = CourseName.values();
		
		// Fill list
		for (int i = 0; i < courseNames.length; i++) {

			// Create course
			Course course = new Course();

			// Set properties
			course.setCode(i);
			course.setName(courseNames[i].getValue());
			course.setCredits(random.nextInt(10) > 5 ? 3 : 6);
			course.setCourseMinutes(random.nextInt(10) > 5 ? 120 : 240);

			// Add to list
			courses.add(course);
		}

		// Return list
		return courses;
	}

	/**
	 * Initialize the course reference fields
	 */
	public static void finishCourseInitialisation() {
		
		
		
		CourseContainer courseContainer = CourseContainer.getInstance();
		List<Course> courses = courseContainer.getCourses();
		//iterate over all courses and set their reference fields.
		CourseMinutes[] courseMinutes = CourseMinutes.values();
		for (int i = 0; i < courses.size(); i++) {
			
			List<Course> requiredCourses = CourseGenerator.getRandomCourses();
			
			//remove the current course from the required courses list if happens to be in there.
			//throws ConccurentModification exception when shutting down... why??
			/*if(requiredCourses.contains(courses.get(i))){
				requiredCourses.remove(courses.get(i));
				
			}*/
			//work around
			List<Course> requiredCourses2 = new ArrayList<Course>();
			for(int j=0; j < requiredCourses.size(); j++){
				if(!requiredCourses.get(j).equals(courses.get(i))){
					requiredCourses2.add(requiredCourses.get(j));
				}
			}
			//set the required courses
			courses.get(i).setRequiredCourses(requiredCourses2);
			
			ArrayList<OfferedCourse> offeredCourses = new ArrayList<OfferedCourse>();
			//initialize a list of offered courses.
			int count = 1+random.nextInt(10);
			for (int j = 0; j < count ; j++) {
				OfferedCourse offeredcourse = new OfferedCourse();
				try{
				offeredcourse.setClassroom(Classroom.values()[1+random
						.nextInt(Classroom.values().length-1)]);
				}catch(Exception e){
					e.printStackTrace();
				}
				offeredcourse.setCourse(courseContainer.getCourses().get(
						random.nextInt(courseContainer.getCourseCount())));

				offeredcourse.setNumberOfPlaces(random.nextInt(15) + 15);
				try {
					offeredcourse.setTimeBlock(new TimeBlock(CourseDay.MONDAY, "15:00", courseMinutes[1+random.nextInt(courseMinutes.length-1)].getValue()));
				} catch (Exception e) {			
					e.printStackTrace();
				}
				TeacherContainer teacherContainer = TeacherContainer.getInstance();
				offeredcourse.setTeacher(teacherContainer.getTeachers().get(random.nextInt(teacherContainer.getTeacherCount())));
				offeredCourses.add(offeredcourse);
			}
			//set the offered courses.
			courses.get(i).setOfferedcourses(offeredCourses);
		}
	}
	
	public static void finishCourseOfferedCourseRegistrationInitiatialisation() {
		CourseContainer courseContainer = CourseContainer.getInstance();
		List<Course> courses = courseContainer.getCourses();
		// iterate over all courses and set their reference fields.

		for (int i = 0; i < courses.size(); i++) {
			Collection<OfferedCourse> offeredCourses = courses.get(i).getOfferedcourses();
			// initialize a list of offered courses.
			for(OfferedCourse offeredcourse : offeredCourses ){
				//offeredcourse.setRegistrations(RegistrationGenerator.getRandomRegistrations());
				offeredcourse.setRegistrations(RegistrationContainer.getInstance().getRegistrationByOfferedCourse(offeredcourse.getPrimaryKey()));
			}

		}
	}
	
	

	public static List<Course> getRandomCourses() {
		CourseContainer courseContainer = CourseContainer.getInstance();
		int toIndex = random.nextInt(courseContainer.getCourseCount());
		int fromIndex = toIndex > 0 ? random.nextInt(toIndex) : 0;
		return courseContainer.getCourses().subList(fromIndex, toIndex);
	}
}
